package com.gmail.dengtao.joe.group.transport.impl;

import com.gmail.dengtao.joe.group.channel.Channel;
import com.gmail.dengtao.joe.group.channel.ChannelListener;
import com.gmail.dengtao.joe.group.interceptor.InterceptorStack;
import com.gmail.dengtao.joe.group.member.MembershipListener;
import com.gmail.dengtao.joe.group.transport.ChannelSender;

/**
 * Abstract Channel Sender.
 * @author <a href="mailto:joe.dengtao@gmail.com">DengTao</a>
 * @version 1.0
 * @since 1.0
 */
abstract class AbstractChannelSender implements ChannelSender {
	
	public static final int DEFAULT_BUFFER_SIZE = 512;

	protected Channel channel;
	protected InterceptorStack interceptorStack = null;	// 
	
	// listeners
	protected MembershipListener membershipListener;
	protected ChannelListener channelListener;
		
	protected int idleTimeForWrite = 0; // idle time for write in seconds.
	protected int sendBufferSize = DEFAULT_BUFFER_SIZE; // use 538 ~ 548, recommend 538 for the best performance.

	protected int selectTimeout = 100;			// If positive, block for up to timeout milliseconds, more or less, while waiting for a channel to become ready; if zero, block indefinitely; must not be negative

	protected boolean start = false;			// Mark whether sender is started.

	@Override
	public int getSelectTimeout() {
		return selectTimeout;
	}

	@Override
	public void setSelectTimeout(int selectTimeout) {
		if (selectTimeout < 0) {
			throw new IllegalArgumentException("Negative timeout:" + selectTimeout);
		}
		this.selectTimeout = selectTimeout;
	}

	@Override
	public int getIdleTimeForWrite() {
		return idleTimeForWrite;
	}

	@Override
	public void setIdleTimeForWrite(int idleTimeForWrite) {
		if (idleTimeForWrite < 0) {
			throw new IllegalArgumentException("Illegal idle time for write: " + idleTimeForWrite);
		}
		this.idleTimeForWrite = idleTimeForWrite;
	}

	@Override
	public void setSendBufferSize(int sendBufferSize) throws IllegalArgumentException  {
		if (sendBufferSize < 0) {
			throw new IllegalArgumentException("Illegal size for send buffer: " + sendBufferSize);
		}
		this.sendBufferSize = sendBufferSize;
	}
	
	/**
	 * Set MembershipListener for this Receiver.
	 * @param membershipListener
	 * @since 1.0
	 */
	public void setMembershipListener(MembershipListener membershipListener) {
		if (membershipListener == null) {
			throw new IllegalArgumentException("MembershipListener can't be null!");
		}
		this.membershipListener = membershipListener;
	}

	/**
	 * Set ChannelListener for this Receiver.
	 * @param channelListener
	 * @since 1.0
	 */
	public void setChannelListener(ChannelListener channelListener) {
		if (channelListener == null) {
			throw new IllegalArgumentException("ChannelListener can't be null!");
		}
		this.channelListener = channelListener;
	}

	public InterceptorStack getInterceptorStack() {
		return interceptorStack;
	}

	public void setInterceptorStack(InterceptorStack interceptorStack) {
		this.interceptorStack = interceptorStack;
	}

}